#第3章 列表和元组
# 索引操作
print("索引操作")
greeting = "Hello"
print(greeting[0])
print(greeting[-1])
print("hello"[1])

# 分片操作
print("分片操作")
number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(number[0:3])
print(number[-1:-3])  # 分片中最左面的元素必须比最右面的元素早出现在序列中
# （并不是指左面的索引比右面的元素数值小），否则就返回一个空序列
print(number[-3:-1])
print(number[-3:0])  # 比如这个时候就会返回空置，所以注意理解上面那句话，
# 即：最左面的元素必须比最右面的元素晚出现在序列中
# （并不是指左面的索引比右面的元素数值小）

# 如果需要取得的分片包括序列结尾的元素，只需将第二个索引设置为空即可
print(number[-3:])
print(number[0:])
print(number[:0])  # 最后一个元素为第一个，
print(number[0:0])
print(number[:3])
print(number[:])  # 输出整个数组

# 步长
print("步长")
print(number[0:10:1])
print(number[0:10:2])
print(number[2:5:3])
print(number[::3])
# print(number[0:10:0]) #输入的步长不能为0
print(number[10:0:-2])
print(number[:5:-2])  # 这个要注意理解一下
print(number[10:0:-1])  # 注意number的最大索引应该是9，索引10指向的是第11个元素，是不存在的。
# 但是由于在最后一个元素之后，因此在分片中能得到最后一个元素，这样做是没问题的。
# 第二个索引为0，取不到序列中的第一个元素
# print(number[10])#但是直接访问的话是不可以的
print(number[10::-1])  # 设置number的第二个索引为空，可以取到序列的一个元素。
print(number[2::-1])  # 设置number的第二个索引为空，可以取到序列的一个元素。
print(number[2:0:-1])  # 第二个索引为0，取不到序列中的第一个元素

# 序列相加
print("序列相加")
a = [1, 2, 3]
b = [4, 5, 6]
print(a + b)
c = ["hello"]
d = ["python"]
print(c + d)
e = "hello,"
f = "python"
print(e + f)
# print(a + e) #不同类型的序列不能通过加号进行序列连接操作

# 序列的乘法
print("序列的乘法")
print("hello" * 5)
print([7] * 10)
# 空置相乘
aa = [None] * 5
print(aa)  # 长度是5的空置
aa = [] * 5
print(aa)  # 只有一个元素是空置，即长度是1的空置

# 成员资格
print("成员资格")
greeting = "hello,world"
print('w' in greeting)
print('a' in greeting)
users = ["C罗", "梅西", "姆巴佩"]
print("C罗" in users)
print("卡卡" in users)
number = [1, 2, 3, 4, 5]
print(1 in number)
print(6 in number)
# print(3 in greeting)#数字类型不能在字符串类型中通过in进行成员资格检测

# 长度、最小值和最大值
print("长度、最小值和最大值")
numbers = [300, 200, 100, 800, 500]
print(len(numbers))
print(max(numbers))
print(min(numbers))

# 元素赋值
print("元素赋值")
a = [1, 2, 3, 2, 1]
a[1] = 10
print(a)
a[2] = "hello"  # 可以对列表中的元素赋不同类型的值
print(a)
# a[5] = 'abc'#对列表中的元素赋值时，不能超过列表的最大编号
print(a)

# 增加元素
print("增加元素")
str = [1, 2, 3]
str.append(4)
print(str)

# 删除元素
print("删除元素")
str = ["a", "b", "c", "d", "e"]
print(len(str))
del str[0]
print(str)
print(len(str))

# 分片赋值
print("分片赋值")
show = list("2018世界杯法国夺冠了")
print(show)
show[7:9] = list("中国")
print(show)
greeting = list("hi")
print(greeting)
greeting[1:] = list("ello")
print(greeting)
# 分片赋值可以在不替换任何原有元素的情况下，在任意位置插入新元素
field = list("ae")
print(field)
field[1:1] = list("bcd")
print(field)
field2 = list("法国夺冠了")
field2[0:0] = list("2018世界杯")
print(field2)
# 分片赋值同样支持类似删除的功能

print("分片赋值删除")
field = list("abcde")
print(field)
field[1:4] = []
print(field)
field2 = list("2018世界杯法国夺冠了")
del field2[0:7]
print(field2)

# 嵌套列表
print("嵌套列表")
field = list("abc")
print(field)
number = [1, 2, 3]
mix = [field, number]
print(mix)
print(mix[0])
print(mix[1])

# list方法，count()
print("list方法，count()")
field = list("hello,python")
print(field.count("o"))

# list方法，extend()方法
print("list方法，extend()方法")
a = ["hello", "world"]
b = ["python", "is", "funny"]
b = ["python", "is", "funny"]
print(a.extend(b))  # extend()方法的返回值是None
print(a)  # 但是extend()方法改变了列表a的值
a = ["hello", "world"]
print(a + b)  # a + b的返回值是将a和b做了拼接
print(a)  # 但是并没有改变a的值，这就是extend()方法和拼接的区别
a[len(a):] = b
print(a)

#append()与extend()的区别
print("append()与extend()的区别")
a = ["hello"]
b = ["python","is","funny"]
a.append(b)#将b做为一个列表追加到a中
print(a)
a = ["hello"]
c = "python,is,funny"
a.append(c)#将b做为一个字符串追加到a中
print(a)
a = ["hello"]
a.extend(b)
print(a)#将b中的元素分别追加到a中
a = ["hello"]
c = "python,is,funny"
a.extend(c)
print(a)

# index()方法
print("index()方法")
field = ["hello", "world", "python", "is", "funny"]
print(field)
print(field.index("hello"))
print(field.index("python"))
# print(field.index("abc"))#不存在时会报错

# insert()方法
print("insert()方法")
number = [1, 2, 3]
print(number)
print(number.insert(2, "插入在2之后3之前"))  # insert方法并没有返回值，而是直接该表了列表的值
print(number)
number = [1, 2, 3]
number[2:2] = ["插入在2之后3之前"]  # 使用分片赋值也能实现同样的功能，但是不如使用insert()方法好理解
print(number)

# pop()方法
field = ["hello", "world", "python", "is", "funny"]
print(field.pop())
print(field)
print(field.pop(1))
print(field)

# remove()方法
print("remove()方法")
field = ["hello", "python", "how", "funny", "python", "is"]
print(field.remove("python"))
print(field)  # 注意只会删除匹配上的第一个元素

# reverse()方法
print("reverse()方法")
number = [1, 2, 3]
print(number.reverse())  # 注意reverse()方法的返回值是None
print(number)  # 但是reverse()方法会改变list的值

# sort()方法
print("sort()方法")
number = [5, 8, 7, 2, 4, 3]
print(number.sort())  # sort()方法并不会返回值
print(number)  # 而是直接改变列表的值
print(sorted(number))  # 使用sorted()方法，则会直接返回列表反转后的结果

# clear()方法
print("clear()方法")
field = ["hello", "python", "how", "funny", "python", "is"]
field.clear()
print(field)

# copy()方法
print("copy()方法")
field = ["hello", "python"]
field2 = field.copy()
print(field2)

# sort()方法
print("sort()方法")
field = ["hello", "python", "funny", "python", "is"]
print(field.sort(key=len, reverse=True))
print(field)

# 元组
print("元组的定义")
number = 1, 2, 3
print(number)  # 这样打印出的是元组
print(1, 2, 3)  # 注意，有意思的是，这样打印时，打印的并不是一个元组。这样打印出来的是什么？
number = (1, 2, 3)  # 加上括号和不加括号的效果是一样的
print(number)
field = "hello", "world"
print(field)
field = ("hello", "world")
print(field)
field = ()
print(field)
field = ("hello",)  # 定义元组时必须得有逗号
print(field)
field = ("hello")  # 如果没有逗号，则仅仅是一个字符串
print(field)

# tuple函数
print("tuple函数")
print(tuple(["hello", "python"]))
print(tuple("hello"))
print(tuple(("hello",)))  # 如果参数是元组，则会被原样返回。

# 访问元组
number = (1, 2, 3)
print(number)
print(number[0])
print(number[0:2])

# 修改元组
number = (1, 2, 3)
number2 = (4, 5, 6)
print(number + number2)

# 删除元组
number2 = (1, 2, 3)
del number2
# print(number2)

# len()函数
number2 = (1, 2, 3)
print(len(number2))
# max()函数
print(max(number2))
# min()函数
print(min(number2))

number2 = (1, 2, 3)
# number2[1] = 4 #元组的值不可以改变

# 嵌套列表
t = (1, 2, ["hello", "python"])
print(t[2][1])
t[2][1] = "world"  # 元组中列表的值可以改变
print(t)
#t[1] = "abc"
print(t)  # 元组的值不可以改变

# 习题
#打印出hello
print("习题")
field = [["hello", "world", "welcome"], ["study", "Python", "is", "funny"], ["good", "better", "best"]]
print(field[0][0])
#打印出Python
print(field[1][1])
#打印出best
print(field[2][2])
#用负数步长对列表和元组进行分片
number2 = list("123465")
print(number2)
#将列表的顺序变为123456
#number2[:-3:-1] = ["6","5"] #用分片赋值的方式实现
number2.sort(reverse=False) #用sort()函数实现
print(number2)
#输出5,3
print(number2[-2:-5:-2])
number2 = tuple(['1', '2', '3', '4', '5', '6'])
print(number2)
#输出5,3
print(number2[-2:-5:-2])